//Copyright (C) 2010 Ron Coleman. Contact: ronncoleman@gmail.com
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 3 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this library; if not, write to the Free Software
//Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

package org.workplicity.cia.table;

import java.util.ArrayList;
import java.util.Calendar;
import javax.swing.table.AbstractTableModel;
import org.workplicity.cia.worklet.ElogsWorklet;
import org.workplicity.elog.entry.ElogUser;
import org.workplicity.elog.entry.Handoff;
import org.workplicity.elog.repos.Handoffs;
import org.workplicity.entry.User;
import org.workplicity.util.Helper;
import org.workplicity.worklet.WorkletContext;

/**
 * This it the table model for the users table.
 * @author Ron Coleman
 */
public class UsersTableModel extends AbstractTableModel {
    private ArrayList<User> users = new ArrayList<User>( );

    private ArrayList<String> elogNames = new ArrayList<String>( );

    private ArrayList<Integer> elogSizes = new ArrayList<Integer>( );

    private ArrayList<Integer> toHandoffCounts = new ArrayList<Integer>( );

    private ArrayList<Integer> fromHandOffCounts = new ArrayList<Integer>( );

    private String[] columnNames = {
        "Id",
        "Logname",
        "Elog",
        "Entries",
        "H/To",
        "H/From"

    };
    
    /**
     * Gets the row count.
     * @return count
     */
    public int getRowCount() {
        return users.size();
    }

    /**
     * Gets the column count.
     * @return Count
     */
    public int getColumnCount() {
        return columnNames.length;
    }

    /**
     * Gets a user field.
     * @param row Table row
     * @param col Table column
     * @returnvalue
     */
    public Object getValueAt(int row, int col) {
        if(row >= users.size())
            return null;

        ElogUser user = getRow(row);

        // Id
        if(col == 0)
            return user.getId();

        // Logname
        if(col == 1)
            return user.getLogname();

        // Elog name
        if(col == 2)
            return elogNames.get(row) + " [" + user.getElogsId() +"]";

        // Elog size
        if(col == 3)
            return elogSizes.get(row);

        // Handoffs from me | to me
        if(col == 4) {
            return
                this.fromHandOffCounts.get(row);

        }

        if(col == 5)
            return this.toHandoffCounts.get(row);
        return null;
    }

    /**
     * Gets the name for a column.
     * @param col Column number.
     * @return Column name
     */
    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    /**
     * Refreshes the users in the model
     */
    public void refresh() {
        // Force a cache refresh (ie, don't wait for the timeout)
        ElogsWorklet.getInstance().getUsersCache().refresh();

        // Fetch users and handoffs for the users
        WorkletContext context =  ElogsWorklet.getInstance().getContext();

        fetchUsers(context);

        fetchHandoffs(context);

        this.fireTableDataChanged();
    }

    /**
     * Gets user in row.
     * @param row Row number (zero-based)
     * @return User
     */
    public ElogUser getRow(int row) {
        if(row >= users.size())
            return null;

        return (ElogUser) users.get(row);
    }

    /**
     * Fetch the users and info about them.
     * member has been set.
     * @param context Worklet context
     */
    private void fetchUsers(WorkletContext context) {
        // Retrieve users from this refreshed cache
        users =  ElogsWorklet.getInstance().getUsersCache().getCache();

        elogNames.clear();
        elogSizes.clear();
        
        for(User user : users) {
            Integer elogId = ((ElogUser) user).getElogsId();

            String criteria = "/list [ id = "+elogId+" ] / title";

            ArrayList<String> list = Helper.query(criteria, context);

            if(list.isEmpty())
                elogNames.add("???");
            else
                elogNames.add(list.get(0));

            criteria = "/list [ id = "+elogId+" ] / size";

            // Retrieve the sizes
            ArrayList<Integer> sizes = Helper.query(criteria, context);

            if(sizes.isEmpty())
                elogSizes.add(-1);
            else
                elogSizes.add(sizes.get(0));
        }
    }

    /**
     * Fetch the handoffs from the last month -- and no more to memory
     * and network capacity.
     * @param context Worklet context
     */
    private void fetchHandoffs(WorkletContext context) {
        long now = System.currentTimeMillis();

        this.fromHandOffCounts.clear();
        this.toHandoffCounts.clear();

        for (User user : users) {
             Integer userId = user.getId();

            String criteria = "/ list [ title = '" + Handoffs.TITLE + "' ] ";
            criteria += "/ list [ ( toId = " + userId + " or fromId = " + userId + ") and ";

            Calendar cal = Calendar.getInstance();

            cal.add(Calendar.MONTH, -1);

            long aMonthAgo = cal.getTimeInMillis();

            criteria += "updateDate >= " + aMonthAgo + " and updateDate <= " + now + " ]";

            ArrayList<Handoff> handoffs = Helper.query(criteria, context);

            int fromUser = 0;
            int toUser = 0;
            for (Handoff handoff : handoffs) {
                if (handoff.getToId().equals(userId)) {
                    toUser++;
                }

                if (handoff.getFromId().equals(userId)) {
                    fromUser++;
                }
            }

            this.toHandoffCounts.add(toUser);
            this.fromHandOffCounts.add(fromUser);
        }
    }

    public void remove(int row) {
        if(row < 0 || row >= users.size())
            return;


    }
}
